home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
shells
/
bashsrc.zoo
/
variables.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-05
|
25KB
|
1,039 lines
/* variables.c -- Functions for hacking shell variables. */
/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <ctype.h>
#include <pwd.h>
#include "shell.h"
#include "flags.h"
#include "version.h"
#ifdef SYSV
struct passwd *getpwuid (), *getpwent ();
#endif
/* The list of shell variables that the user has created, or that came from
the environment. */
SHELL_VAR *variable_list;
/* The current variable context. This is really a count of how deep into
executing functions we are. */
int variable_context = 0;
/* The array of shell assignments which are made only in the environment
for a single command. */
char **temporary_env = (char **)NULL;
/* Some funky variables which are known about specially. Here is where
"$*", "$1", and all the cruft is kept. */
char *dollar_vars[10];
WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
/* The value of $$. */
int dollar_dollar_pid;
/* An array which is passed to commands as their environment. It is
manufactured from the overlap of the initial environment and the
shell variables that are marked for export. */
char **export_env = (char **)NULL;
/* Non-zero means that we have to remake EXPORT_ENV. */
int array_needs_making = 1;
/* The list of variables that may not be unset in this shell. */
char **non_unsettable_vars = (char **)NULL;
#ifdef SYSV
#define DEFAULT_MAIL_PATH "/usr/mail/"
#else
#define DEFAULT_MAIL_PATH "/usr/spool/mail/"
#endif
/* Initialize the shell variables from the current environment. */
initialize_shell_variables (env)
char *env[];
{
extern char *primary_prompt, *secondary_prompt;
char *name, *string;
int c, char_index;
int string_index = 0;
SHELL_VAR *temp_var;
while (string = env[string_index++])
{
char_index = 0;
name = (char *)alloca (1 + strlen (string));
while ((c = *string++) && c != '=')
name[char_index++] = c;
name[char_index] = '\0';
/* If exported function, define it now. Sigh. */
if (strncmp ("() {", string, 4) == 0)
{
char *eval_string =
(char *)xmalloc (3 + strlen (string) + strlen (name));
sprintf (eval_string, "%s %s", name, string);
parse_and_execute (eval_string, name);
}
else
bind_variable (name, string);
set_var_auto_export (name);
}
/* Remember this pid. */
dollar_dollar_pid = getpid ();
/* Now make our own defaults in case the vars that we think are
important are missing. */
set_if_not ("PATH", DEFAULT_PATH_VALUE);
set_var_auto_export ("PATH");
set_if_not ("TERM", "dumb");
set_var_auto_export ("TERM");
set_if_not ("PS1", primary_prompt);
set_if_not ("PS2", secondary_prompt);
set_if_not ("IFS", " \t\n");
/* Magic machine types. Pretty convenient. */
bind_variable ("HOSTTYPE", HOSTTYPE);
/* Default MAILPATH, and MAILCHECK. */
set_if_not ("MAILCHECK", "60");
if ((get_string_value ("MAIL") == (char *)NULL) &&
(get_string_value ("MAILPATH") == (char *)NULL))
{
extern char *current_user_name;
char *tem;
tem = (char *)xmalloc (1 + sizeof (DEFAULT_MAIL_PATH)
+ strlen (current_user_name));
strcpy (tem, DEFAULT_MAIL_PATH);
strcat (tem, current_user_name);
bind_variable ("MAILPATH", tem);
free (tem);
}
/* Set up $PWD. */
{
char *get_working_directory (), *cd;
cd = get_working_directory ("shell-init");
if (cd)
{
bind_variable ("PWD", cd);
free (cd);
}
}
/* Do some things with shell level. */
{
extern int shell_level;
char new_level[10];
int old_level;
set_if_not ("SHLVL", "0");
set_var_auto_export ("SHLVL");
sscanf (get_string_value ("SHLVL"), "%d", &old_level);
shell_level = old_level + 1;
sprintf (new_level, "%d", shell_level);
bind_variable ("SHLVL", new_level);
}
/* Get the full pathname to THIS shell, and set the BASH variable
to it. */
{
extern char *shell_name, *find_user_command (), *full_pathname ();
extern int login_shell;
char *tname = find_user_command (shell_name);
if ((login_shell == 1) && (*shell_name != '/'))
{
struct passwd *entry = getpwuid (getuid ());
if (entry)
{
/* If HOME doesn't exist, set it. */
temp_var = (SHELL_VAR *)find_variable ("HOME");
if (!temp_var)
{
temp_var = bind_variable ("HOME", entry->pw_dir);
temp_var->attributes |= att_exported;
}
name = savestring (entry->pw_shell);
}
else
name = savestring ("a.out");
}
else
{
if (!tname)
{
char *make_absolute ();
name = make_absolute (shell_name, get_string_value ("PWD"));
}
else
{
name = full_pathname (tname);
free (tname);
}
}
/* Make the exported environment variable SHELL be whatever the name of
this shell is. Note that the `tset' command looks at this variable
to determine what style of commands to output; if it ends in "csh",
then C-shell commands are output, else Bourne shell commands. */
set_if_not ("SHELL", name);
set_var_auto_export ("SHELL");
/* Make a variable called BASH, which is the name of THIS shell. */
temp_var = bind_variable ("BASH", name);
temp_var->attributes |= att_exported;
free (name);
}
/* Make a variable called BASH_VERSION which contains the version info. */
{
char tt[12];
extern char *dist_version;
extern int build_version;
sprintf (tt, "%s.%d", dist_version, build_version);
bind_variable ("BASH_VERSION", tt);
}
/* Set history variables to defaults, and then do whatever we would
do if the variable had just been set. */
{
char *tilde_expand ();
char *tem = tilde_expand ("~/.bash_history");
set_if_not ("HISTFILE", tem);
free (tem);
set_if_not ("HISTSIZE", "500");
sv_histsize ("HISTSIZE");
}
/* Gee, might as well get parent pid. */
{
char aval[10];
sprintf (aval, "%d", getppid ());
bind_variable ("PPID", aval);
}
non_unsettable ("PATH");
non_unsettable ("PS1");
non_unsettable ("PS2");
non_unsettable ("IFS");
/* Get the users real user id, and save that in an readonly variable.
To make the variable *really* readonly, we have added it to a special
list of vars. */
sv_uids ();
set_var_read_only ("UID");
set_var_read_only ("EUID");
non_unsettable ("EUID");
non_unsettable ("UID");
}
/* Add NAME to the list of variables that cannot be unset
if it isn't already there. */
non_unsettable (name)
char *name;
{
register int i;
if (!non_unsettable_vars)
{
non_unsettable_vars = (char **)xmalloc (1 * sizeof (char *));
non_unsettable_vars[0] = (char *)NULL;
}
for (i = 0; non_unsettable_vars[i]; i++)
if (strcmp (non_unsettable_vars[i], name) == 0)
return;
non_unsettable_vars =
(char **)xrealloc (non_unsettable_vars, (2 + i) * sizeof (char *));
non_unsettable_vars[i] = savestring (name);
non_unsettable_vars[i + 1] = (char *)NULL;
}
/* Set NAME to VALUE if NAME has no value. */
set_if_not (name, value)
char *name, *value;
{
char *temp = get_string_value (name);
if (!temp)
bind_variable (n